#ifndef DRYCTRL_THREAD_H
#define DRYCTRL_THREAD_H
#include <QThread>
#include <QDateTime>
#include "KgGlobalData.h"
#include "ioreader.h"
#include "QNetDebug.h"
#include "ComStruct.h"
//ZZ-IO404 或 ZZ-IO606 线程
class CBattStack;
class CRTDB;
class DryCtrlThread : public QThread
{
	Q_OBJECT
    friend void updateDryDataToRtdb(DryCtrlThread *pThread);
public:
	DryCtrlThread(QObject *parent);
	~DryCtrlThread();
public:
	void run();
	int readDevDIState(CBattStack *pStack, quint16 &connFailedCount); // 读取DI1--DI6的状态并判断消防告警                         // 读取DO1--DO6的状态
	void setSomeDOState();
    bool setDoState0(quint16 doIndex, quint16 usSetVal);//控制DO口是否闭合(打开继电器)
	bool setDoState(quint16 &IOCtrl, quint16 doIndex, quint16 usSetVal);// added 2023-12-17
    void ctrlErrorLamp(CBattStack *pStack);
    void printRealState(quint16 usHasProt, quint16 usEmergStopAlarm);

	// added 2023-06-17
    void JudgeXfMotion(int &xfAlarmCount, int &xfMotionCount, int &xfErrorCount, int &xfctrlDlqCount, int runCount);
	void JudgeYljError(int &yljProtCount, int &xfctrlDlqCount, int runCount);// added 2023-10-25
	void TellPcsError(int xfMotionCount, int runCount, int needTkQlq);
	void JudgeDIState(); // 判断各簇QF1开关状态 // added 2023-6-23
	void SaveEmsFltkLog(); // 记录下EMS控制高压箱分励脱扣日志 // added 2023-6-23 
	int  GetCloseDlqCount();// 获取总交流断路器，直流断路器总合闸个数
	
    quint16 waitFzOpt(quint16 ctrlType, quint16 &drvFzCount, quint16 &drvFzSuccedCount, QDateTime &drvFzTime, QDateTime statChangeTime);
	quint16 waitHzOpt(quint16 ctrlType, quint16 &drvHzCount, QDateTime &drvHzTime);
	void parseStackState(quint16 stackState, quint16 &usHasProt, quint16 &usHasAlarm,
		quint16 &usChargeFull, quint16 &usDischargeEmpty, quint16 &usProhibitChgDchg);
	quint16 getConfSwitchState(CBattStack *pStack, DI_STU diStu);// 	获取汇流开关反馈状态 1-合闸 0-分闸
	quint16 getClosedConfSwitchCount();
	QString getConfSwitchStrState();
	bool controlHzFz();
	bool sendHzFzCmd(quint16  usDrvHz, quint16  usDrvFz); // added 2022-11-17
	void controlOtherFz();
	void dealwithConnFailed(int runCount);
	void readDIValue(quint16 runCount);
	
    void dealWithConfSwitchStrategy(CBattStack *pStack);
	quint16 getConfSwitchState();// 	获取汇流开关反馈状态 1-合闸 0-分闸
	quint16 getIsolSwitchAggrState();
	quint16 hasEmertStopAlarm();// added 2022-1-25
	quint16 hasFireAlarm();
	quint16 hasWaterAlarm();
	bool isRemoteMode(); // added 2024-5-4
	bool isAllBankFault(); // added 2025-2-20
	
    static int readBcmuAddressMode(); // 读取地址分配模式
    static bool readIsOneClickAllocate(); // 读取一键分配配置
    static void writeBcmuAddressMode(int mode); // 写入地址分配模式
    static void writeIsOneClickAllocate(bool enable); // 写入一键分配配置
    // 设置手动地址分配请求标志
    void setAddressAllocRequest(bool request);
    void dealwithAutoAllocAddr(DOStrategy doStg);
    void dealwithBcmuAddressAllocation();

    void triggerBcmuAddressAlloc();
    void checkBcmuAddressAllocManuTrigger();   //手动分配
    void checkBcmuAddressAllocAutoTrigger();   //自动分配
    void setAddressAllocRequestToZero();
private:
	void judgeXfAlarm();        //  9
    void judgeXfSparyAlarm(); //  25
    void judgeXfFaultAlarm();  //  26
	void judgeXfAutoManu();  //  27
	void judgeXfMotionMsg(); // 14
	void judgeXfWarmMsg();  // 22
	void judgeElecPowerOff();//  30
	void judgeWaterAlarm();
	void judgeThunderAlarm();
	void judgeEmergeStop();
	void judgeFuseAlarm();
	void judgetConfSwitchState(CBattStack *pStack);
	void judgeIsolSwitchAggrState();
	void judgeMainSwitchState();
	void updateDIStateToIniFile(); // 更新DI状态到ini文件
	void lszhParseDLQState(quint16 &usHasProt);
	void judgeChgJcqState();
	void judgeCombusGasAlarm();
	bool hasCombusGasAlarm();
	void judgeUpsAlarm();// added 2022-11-8
	void judgeDoorAlarm();
	void judgetResState();
	void judgeExtState();
	char hasResBreakAlarm();        // added 2025-2-12
	void judgeAcFault();
	void judgeLqFault();
	void judgeBmsSmokeAlarm();
	void judgeBmsHeatAlarm();

	void judgeDoorAlarmSec(); // added 2023-12-21
	void judgeWaterAlarmSec();
	void judgeEmergeStopSec();
	void judgeThunderAlarmSec();
	void judgeBmsLocalState();// added 2023-12-25
	void judgeBmsRemoteState();

	void judgeObj(XFStrategy &obj, quint16 usDIVal, quint16 &alarmCount, quint16  &alarmState, QString strName);

	void sendLog(int iLogType, const QString& strLog);
private:
	IOReader   *m_pIOReader;

	quint16 m_fireAlarmCount;
	quint16 m_fireSignal;     // 1:消防信号 0:无 (只记录日志不通知BA）
	quint16 m_fireAlarm;      // 1:消防告警 0:正常
	//quint16 m_fireDetectAlarm;// added 2022-5-25
	quint16 m_oldFireAlarm;

	quint16 m_fireSprayCount;      // added 2022-12-10
	quint16 m_fireSpraySignal;     // 1:消防信号 0:无 (只记录日志不通知BA）
	quint16 m_fireSprayAlarm;      // 1:消防告警 0:正常
	quint16 m_oldFireSprayAlarm;

	quint16 m_fireFaultCount;      // added 2022-12-21
	quint16 m_fireFaultAlarm;      // 1:消防故障 0:正常

	quint16 m_fireManuCount;      // added 2023-11-9
	quint16 m_fireManuMode;       // 1:消防手动 0:消防自动

	quint16 m_elecPowerOffCount;   // added 2023-11-9
	quint16 m_elecPowerOffAlarm;   // 1:市电断电 0:正常

	quint16 m_waterCount;
	quint16 m_waterSignal;     // 1:水浸信号 0:无 (只记录日志不通知BA）
	quint16 m_waterAlarm;      // 1:水浸告警 0:正常

	quint16 m_thunderCount;
	quint16 m_thunderSignal;  // 1:防雷信号 0:无 (只记录日志不通知BA）
	quint16 m_thunderAlarm;   // 1:防雷告警 0:正常

	quint16 m_fuseCount;
	quint16 m_fuseSignal;    // 1:熔断器信号 0:无 (只记录日志不通知BA） // added
	quint16 m_fuseAlarm;     // 1:熔断器告警 0:正常

	quint16 m_xfMotionCount;
	quint16 m_xfMotionAlarm;  // 1:消防释放 0:无  // added 2022-4-6

	quint16 m_xfWarmCount;
	quint16 m_xfWarmMsg;     // 1:消防预警 0:无  // added 2022-6-6

	quint16 m_upsAlarmCount;
	quint16 m_upsAlarm;      // 1:UPS告警  0:无  // added 2022-11-8

	quint16 m_doorAlarmCount;
	quint16 m_doorAlarm;     // 1:门禁告警  0:无  // added 2022-11-8

	quint16 m_doorAlarmCountSec;
	quint16 m_doorAlarmSec;     // 1:门禁告警  0:无  // added 2023-5-4

	quint16 m_emergStopCount;
	quint16 m_emergStopSignal; // 1:急停信号 0:无 (只记录日志不通知BA）
	quint16 m_emergStopAlarm;  // 1:急停  0:正常
	quint16 m_usOldEmerStopState; // added 2022-1-12

	quint16 m_waterCountSec;
	quint16 m_waterSignalSec;     // 1:水浸信号 0:无 (只记录日志不通知BA）
	quint16 m_waterAlarmSec;      // 1:水浸告警 0:正常

	quint16 m_thunderCountSec;
	quint16 m_thunderSignalSec;  // 1:防雷信号 0:无 (只记录日志不通知BA）
	quint16 m_thunderAlarmSec;   // 1:防雷告警 0:正常

	quint16 m_emergStopCountSec;
	quint16 m_emergStopSignalSec; // 1:急停信号 0:无 (只记录日志不通知BA）
	quint16 m_emergStopAlarmSec;  // 1:急停  0:正常

	quint16 m_bmsLocalCount;
	quint16 m_bmsLocalSignal;
	quint16 m_bmsLocalState;     // 1:BMS就地 0:BMS远方

	quint16 m_bmsRemoteCount;
	quint16 m_bmsRemoteSignal;
	quint16 m_bmsRemoteState;   // 1:BMS远方 0:S就地

	quint16 m_combusGasCount;
	quint16 m_combusGasSignal;// 1:可燃气体信号 0:无 (只记录日志不通知BA）
	quint16 m_combusGasAlarm; // 1:可燃气体告警 0:正常
	quint16 m_combusGasDetectAlarm; // added 2022-5-25

	quint16 m_isolSwitchClosedCount; // 隔离开关闭合记数 // added 2022-03-30
	quint16 m_isolSwitchOpendCount;  // 隔离开关断开记数 

	quint16 m_mainSwitchCount;   // added 2024-1-23
	quint16 m_mainSwitchClosed;  // 主断路器状态 1:闭合 0:断开

	quint16 m_acFaultCount;
	quint16 m_acFault;           // 1:空调故障     0:无 

	quint16 m_lqFaultCount;
	quint16 m_lqFault;          // 1:液冷机故障      0:无 

	
	quint16 m_bmsSmokeCount;
	quint16 m_bmsSmokeAlarm;
    quint16 m_bmsSmokeMotionLogCount;
	
	quint16 m_bmsHeatCount;
	quint16 m_bmsHeatAlarm;
	quint16 m_bmsHeatMotionLogCount;
	
	quint16 m_hlkgState[MAX_HLKG_COUNT];   // 汇流开关反馈，一般只有1个
	quint16 m_glkgState[MAX_GLKG_COUNT];   // 隔离开关反馈

	quint16 m_xfTkMotionCount;// 消防脱扣执行次数
	quint16 m_xfTkMotionLogCount;

	quint16 m_xfSprayTkMotionCount;// 消防喷洒脱扣执行次数 // added 2022-12-10
	quint16 m_xfSprayTkMotionLogCount;
	quint16 m_emgTkMotionLogCount;

	quint16 m_waterTkMotionLogCount;
	quint16 m_volDownProtTkCount;
	quint16 m_volDownProtTkLogCount;

	int   m_oldBankState[MAX_BANK_NUM];// added 2023-7-29
	quint16 m_reservedCount[RES_STRATEGY_COUNT];
	quint16 m_reservedAlarm[RES_STRATEGY_COUNT];

	quint16 m_extCount[EXT_STRATEGY_COUNT];
	quint16 m_extAlarm[EXT_STRATEGY_COUNT];// 新增策略

private:
	quint16   m_stackState;    // 当前堆状态
	QDateTime m_statChangeTime;// 堆状态改变时间
	
	quint16   m_drvFzCount;   // 已发送分闸/脱扣命令记数
	quint16   m_drvFzSuccedCount;// added 2022-1-11
	QDateTime m_drvFzTime;    // 最近一次驱动分闸时间

	quint16   m_drvHzCount;   // 已发送合闸命令记数
	quint16   m_drvHzSuccedCount;
	QDateTime m_drvHzTime;    // 最近一次驱动合闸时间
	quint16   m_oldConnState; //  并网连接状态 

	quint16   m_masterFzCount;// 主动分闸记数
	quint16   m_masterHzCount;// 主动合闸记数

	quint16   m_saveEmsCtrlHzRdCount;// 保存EMS控制汇流开关记录后计时
	quint16   m_saveEmsCtrlFzRdCount;
	quint16   m_saveRejectEmsHzRdCount;

	quint16   m_detectYcCount;
	quint16   m_detectOkCount;

	quint16 m_usOldHasAlarm;
	quint16 m_usOldHasProt;

	quint16 m_usOldChgJcqState;
	quint16 m_usOldDchgJcqState;

	quint16 m_usConnFailed;  // 是否有通迅故障 0:无 1:有, 99:没有初始化
	quint16 m_signalLogCount; // 共用, 用于不过多产生日志

	int  m_xfAlarmLog;
	int  m_xfXfMotionLog;
	int  m_xfXfErrorLog;

	int  m_yljErrorLog;

	int  m_hasReadIoState;
	quint16 m_usOldDI[16];

	int  m_bankFaultTimeCount[10];

	quint16 m_oldCtrlFanState; // added 2023-12-17
	quint16 m_closeFanReqCount;
	QDateTime m_closeReqStartTime;

	char m_tmpBuf[200];
	CRTDB *m_pRTDB;
	CBattStack *m_pStack;

    // 地址分配请求标志
    int m_bcmuAddrAllocReq=0;
        // 上次BCMU连接故障状态，用于检测变化
    char m_lastBcmuConnFault[30];

    QNetDebug *netDebug ;


    int m_doCloseCounter ; //DO 关闭的循环次数
    bool m_addressAllocCommandSent;

private:                       //dinggong
    void handleFireAlarm(); // 处理消防告警触发的脱扣操作，包括打开DO、记录日志和关闭DO等流程
    void handleFireSprayAlarm(); // 处理消防喷洒告警触发的脱扣操作，针对喷洒、烟感、温感等多种告警情况
    void handleVolDownProtection(); // 处理低电压保护触发的脱扣操作，执行脱扣操作并记录相关日志
    void logAlarmEvents(const QString &strDoName); // 记录消防告警相关事件的日志，包括火灾告警、喷洒告警和急停告警
    void logSprayAlarmEvents(const QString &strDoName); // 记录喷洒告警相关事件的日志，包括喷洒、急停、水浸、烟感和温感告警
    void executeCommandAndWait(); // 执行DO控制命令并等待200ms，确保命令执行完毕
    void resetFireAlarmCounters(); // 重置所有与消防告警相关的计数器，用于清除告警状态
    void resetSprayAlarmCounters(); // 重置所有与喷洒告警相关的计数器，用于清除喷洒告警状态

    // 重置默认打开的触点
    void resetDefaultOpenContacts(quint16 &newIOCtrl);
    // 设置烟雾和热驱动触点
    void setSmokeAndHeatDriveContacts(quint16 &newIOCtrl);
    // 设置BCMU地址分配触点
    void setBcmuAddressAllocationContacts(quint16 &newIOCtrl);
    // 设置温度驱动触点
    void setTemperatureDriveContacts(quint16 &newIOCtrl);
    // 处理风扇延迟关闭
    void handleFanDelayedShutdown(quint16 &newIOCtrl, int doIndex);
    // 设置风扇驱动触点
    void setFanDriveContacts(quint16 &newIOCtrl, quint16 usEmergStopAlarm);
    // 设置BMS与EMS通讯故障触点
    void setBmsEmsCommFaultContacts(quint16 &newIOCtrl);
    // 设置雷击动作触点
    void setLightningActionContacts(quint16 &newIOCtrl);
    // 设置消防喷淋动作触点
    void setFireSprayActionContacts(quint16 &newIOCtrl);
    // 设置火灾动作触点
    void setFireActionContacts(quint16 &newIOCtrl);
    // 设置登记控制触点
    void setRegisterControlContacts(quint16 &newIOCtrl);
    // 设置放电驱动触点
    void setDischargingDriveContacts(quint16 &newIOCtrl, quint16 usHasProt, quint16 usDischargeEmpty, quint16 usProhibitChgDchg, quint16 usEmergStopAlarm);
    // 设置充电驱动触点
    void setChargingDriveContacts(quint16 &newIOCtrl, quint16 usHasProt, quint16 usChargeFull, quint16 usProhibitChgDchg, quint16 usEmergStopAlarm);
    // 设置禁止放电触点
    void setDischargingProhibitContacts(quint16 &newIOCtrl, quint16 usHasProt, quint16 usDischargeEmpty, quint16 usProhibitChgDchg, quint16 usEmergStopAlarm);
    // 设置禁止充电触点
    void setChargingProhibitContacts(quint16 &newIOCtrl, quint16 usHasProt, quint16 usChargeFull, quint16 usProhibitChgDchg, quint16 usEmergStopAlarm);
    // 记录报警状态变化
    void logAlarmStateChange(int doIndex, quint16 usHasAlarm);
    // 设置报警触点
    void setAlarmContacts(quint16 &newIOCtrl, quint16 usHasAlarm);
    // 设置常亮指示灯触点
    void setConstantLightContacts(quint16 &newIOCtrl);
    // 设置运行指示灯触点
    void setRunningLightContacts(quint16 &newIOCtrl, quint16 usHasProt, quint16 usEmergStopAlarm);
    // 设置所有电池组故障触点
    void setAllBankFaultContacts(quint16 &newIOCtrl);
    // 设置故障干触点
    void setFaultDryContacts(quint16 &newIOCtrl, quint16 usHasProt, quint16 usEmergStopAlarm);
    // 记录当前状态
    void logCurrentState(quint16 usHasProt, quint16 usHasAlarm, quint16 usChargeFull, quint16 usDischargeEmpty);
    // 更新旧状态
    void updateOldStates(quint16 usEmergStopAlarm);
    // 重置驱动计数器
    void resetDriveCounters();
    // 等待状态变化
    void waitForStateChange(quint16 &usEmergStopAlarm);

};

#endif // DRYCTRL_THREAD_H
